package com.urbansquall.ginger
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.PixelSnapping;
	import flash.display.Sprite;
	import flash.geom.Matrix;

	/**
	 * 
	 * @author Colbycheeze
	 * @description Internal class to be used by the AnimationPlayer.
	 * 
	 */
	internal class Frame
	{
		private var m_debugID : Number;
		
		public var numFrames: int;
		public var bitmapData: Array;
		public var width: Array;
		public var height: Array;
		public var offsetX : Array;
		public var offsetY : Array;
		public var frameID: String;
		
		public function toString() : String
		{
			return "<Frame (" + m_debugID +") bitmapData:" + bitmapData.length + " numFrames:" + numFrames + " frameID:" + frameID + " offsetX:" + offsetX + " offsetY:" + offsetY + ">";
		}
		
		public function Frame( a_numFrames: int, a_bitmapData: BitmapData,
			a_numRotations: int, a_frameID: String, a_offsetX: Number = 0, a_offsetY : Number = 0 )
		{
			m_debugID = Math.random();
			numFrames = a_numFrames;
			frameID = a_frameID;
			bitmapData = [];
			width = [];
			height = [];
			
			offsetX = [];
			offsetY = [];
			
			if( a_numRotations == 1 )
			{
				createFrameWithNoRotation( a_bitmapData, a_offsetX, a_offsetY );
			}
			else
			{
				createRotatedFrame( a_bitmapData, a_numRotations, a_offsetX, a_offsetY );
			}
		}
		
		public function changeID( a_id : String ) : void
		{
			frameID = a_id;
		}
		
		private function createFrameWithNoRotation( a_bitmapData: BitmapData, a_offsetX: Number = 0, a_offsetY : Number = 0 ) : void
		{
			bitmapData.push( a_bitmapData );
			width.push( a_bitmapData.width );
			height.push( a_bitmapData.height );
			offsetX.push( -a_offsetX );
			offsetY.push( -a_offsetY );
		}
		
		private function createRotatedFrame( a_bitmapData: BitmapData, a_numRotations: int, a_offsetX: Number = 0, a_offsetY : Number = 0 ) : void
		{			 
			 // In order to determine how large the bitmap must be in order to rotate the image, we must
			 // find the largest side of the X and Y. We then find the amount of offset to place the object in
			 // so that it is centered within the bitmap, that way it can rotate w/o being cut off at any point
			var largeSideX:int = Math.max( Math.abs(a_offsetX), a_offsetX + a_bitmapData.width );
			var largeSideY:int = Math.max( Math.abs(a_offsetY), a_offsetY + a_bitmapData.height );
			
			var tx:Number = ( largeSideX ) * Math.SQRT2;
			var ty:Number = ( largeSideY ) * Math.SQRT2;
			
			var maxTxy:Number = Math.max( tx, ty );

			var bdSize:Number = Math.ceil( Math.max( largeSideX*2, largeSideY*2 ) * Math.SQRT2 );
			var mat:Matrix = new Matrix( 1, 0, 0, 1, maxTxy, maxTxy );
	 		var bd:BitmapData = new BitmapData( bdSize, bdSize, true, 0 );
			
			var container:Sprite = new Sprite();
 			var bmpHolder:Sprite = new Sprite();
 			var bmpData:BitmapData = new BitmapData( largeSideX, largeSideY, true, 0 );
 			var bmp:Bitmap = new Bitmap( a_bitmapData, PixelSnapping.ALWAYS, true );
 			bmp.x = a_offsetX;
 			bmp.y = a_offsetY;
 			bmpHolder.addChild(bmp);
 			container.addChild(bmpHolder);

 			var ri:int = 0;
 			while( ri < a_numRotations )
 			{
 				bd.fillRect( bd.rect, 0x0 );
 				bd.draw( container, mat );
				
 				bitmapData[ ri ] = bd.clone();
 				width[ ri ] = bmpHolder.width;
 				height[ ri ] = bmpHolder.height;			
				
				offsetX[ ri ] = maxTxy;
				offsetY[ ri ] = maxTxy;

 				bmpHolder.rotation += 360 / a_numRotations;

 				ri++;
 			}
		}
	}
}
	

